package com.stark.commons.spring.core.boot.config;

import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.transaction.jta.JtaProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.jta.JtaTransactionManager;
import org.springframework.util.StringUtils;

import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.icatch.jta.UserTransactionManager;
import com.atomikos.icatch.provider.ConfigProperties;
import com.stark.commons.spring.core.support.jta.AtomikosJtaPlatform;

/**
 * 基于 atomikos 实现的 jta 事务配置。
 * <ul>
 * <li>仅在配置文件中显示指定 <code>spring.jta.enabled=true</code> 时生效。</li>
 * </ul>
 * @author Ben
 * @since 1.0.0
 * @version 1.0.0
 */
@Configuration
@ConditionalOnProperty(prefix = "spring.jta", name = "enabled", havingValue = "true")
public class AtomikosJtaAutoConfig {
	
	@Autowired
	private JtaProperties jtaProperties;
	
	@Bean
	public UserTransaction userTransaction() throws SystemException {
		applyJtaProperties();
		
		UserTransactionImp userTransactionImp = new UserTransactionImp();
		userTransactionImp.setTransactionTimeout(10000);
		return userTransactionImp;
	}

	@Bean(initMethod = "init", destroyMethod = "close")
	public TransactionManager atomikosTransactionManager() {
		UserTransactionManager userTransactionManager = new UserTransactionManager();
		userTransactionManager.setForceShutdown(false);

		AtomikosJtaPlatform.transactionManager = userTransactionManager;

		return userTransactionManager;
	}

	@Bean
	@DependsOn({ "userTransaction", "atomikosTransactionManager" })
	public PlatformTransactionManager transactionManager() throws SystemException {
		UserTransaction userTransaction = userTransaction();

		AtomikosJtaPlatform.transaction = userTransaction;

		TransactionManager atomikosTransactionManager = atomikosTransactionManager();
		return new JtaTransactionManager(userTransaction, atomikosTransactionManager);
	}
	
	private void applyJtaProperties() {
		ConfigProperties configProperties = com.atomikos.icatch.config.Configuration.getConfigProperties();
		if (StringUtils.hasText(jtaProperties.getTransactionManagerId())) {
			configProperties.setProperty(ConfigProperties.TM_UNIQUE_NAME_PROPERTY_NAME,
					jtaProperties.getTransactionManagerId());
		}
		if (StringUtils.hasText(jtaProperties.getLogDir())) {
			configProperties.setProperty(ConfigProperties.LOG_BASE_DIR_PROPERTY_NAME,
					jtaProperties.getLogDir());
		}
	}
	
}
